/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-05-12
*/
package com.rzico.order.controller.admin;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rzico.account.entity.Receivable;
import com.rzico.account.service.PaymentService;
import com.rzico.account.service.ReceivableService;
import com.rzico.annotation.Log;
import com.rzico.base.BaseController;
import com.rzico.base.CommResult;
import com.rzico.basics.entity.*;
import com.rzico.basics.service.*;
import com.rzico.core.entity.SysEmployee;
import com.rzico.core.entity.SysOffice;
import com.rzico.core.entity.SysReport;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.*;
import com.rzico.entity.PageResult;
import com.rzico.entity.Pageable;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.WarehouseTypeEnum;
import com.rzico.order.service.*;
import com.rzico.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.jasperreports.engine.JRException;
import org.apache.commons.lang3.time.DateUtils;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 退货单项控制层
 *
 * @author Rzico Boot
 * @version 1.0
 * @date 2020-05-12
 */
@Api(description = "退货单项接口")
@RestController
@RequestMapping("/admin/return")
public class ReturnAdminController extends BaseController {

    @Value("${rzico.filePath.windows}")
    private String windowsFilePath;

    @Value("${rzico.filePath.linux}")
    private String linuxFilePath;

    @Autowired
    private ReturnService returnService;

    @Autowired
    private ReturnItemService returnItemService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private SysOfficeService sysOfficeService;

    @Autowired
    private ProductService productService;

    @Autowired
    protected SysEmployeeService sysEmployeeService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SysReportService sysReportService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private SupplierService supplierService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private ReceivableService receivableService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private OrderLogService orderLogService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private SysUserDataScopeService sysUserDataScopeService;

    @Autowired
    private VirtualProductService virtualProductService;

    /**
     * 分页查询退货单项
     *
     * @return
    */
    @ApiOperation("分页查询退货单项")
    @GetMapping("/list")
    @ApiImplicitParams({@ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String", paramType = "query") ,
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "supplierId", value = "供应商ID", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "memberId", value = "客户ID", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "productId", value = "商品ID", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "收货电话", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sn", value = "退货单号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "orderSn", value = "销售单号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "shippingStatus", value = "状态", dataType = "Integer", paramType = "query")
    })
    public CommResult<Return> list(Date startDate, Date endDate, String sn, String orderSn, Long supplierId,Long memberId, Integer shippingStatus, Long productId, String phone, Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);
        if (startDate!=null){
            params.put("startDate", DateUtils.truncate(startDate, Calendar.DATE));
        }
        if (endDate!=null){
            params.put("endDate", DateUtils.addMilliseconds(DateUtils.addDays(endDate,1),-1));
        }
        if (StringUtils.isNotEmpty(sn)){
            params.put("sn", sn);
        }
        if (StringUtils.isNotEmpty(orderSn)){
            params.put("orderSn", orderSn);
        }
        if (null != productId){
            Product product = productService.findById(productId);
            params.put("goodsId", product.getGoodsId());
        }
        if (null != phone){
            params.put("phone", phone);
        }
        params.put("deleted", false);


        if (supplierId!=null) {
            params.put("supplierId",supplierId);
        }

        if (memberId!=null) {
            params.put("memberId",memberId);
        }

        if (shippingStatus!=null) {
            params.put("shippingStatus",shippingStatus);
        }

        Enterprise enterprise = enterpriseService.getCurrent();
        if (enterprise!=null) {
            params.put("enterpriseId", enterprise.getId());
        } else {
            return CommResult.error("没有开通企业");
        }


        //检查是否供应商账号
        SysUser sysUser = sysUserService.getCurrent();
        Supplier supplier = supplierService.findByUserId(sysUser.getId());
        if (supplier!=null) {
            params.put("supplierId",supplier.getId());
        } else {
            //非管理员都启用数据权限
            if (!sysUserService.isAdmin(sysUser)) {
//                params.put("dataScopeId",sysUser.getId());
                if (sysUserDataScopeService.checkHasPermissio(sysUser.getId(),2)) {
                    if (sysUser.getMchId().equals(enterprise.getMchId())) {
                        params.put("shopScopeId", sysUser.getId());
                    }
                } else {
                    SysEmployee sysEmployee = sysEmployeeService.getCurrent();
                    if (sysEmployee==null) {
                        return CommResult.error("无效员工账号");
                    }
                    params.put("shippingEmployeeId",sysEmployee.getId());
                }
            }
        }

        if (supplierId!=null){
            params.put("supplierId", supplierId);
        }

        Page<Object> startPage = PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<Return> list = returnService.selectList(params);
        PageResult<Return> pageResult = new PageResult<Return>(list, startPage.getTotal(), pageable);
        return CommResult.success(pageResult);
    }


    /**
     * 统计末完成退货单
     *
     * @return
     */
    @ApiOperation("统计末完成退货单")
    @PostMapping("/summary")
    public CommResult<Order> summary() {

        Enterprise enterprise = enterpriseService.getCurrent();

        Map<String,Object> data = new HashMap<>();
        Map<String,Object> params = new HashMap<>();

        //退货状态(1:未确认,3.已退货,4.已完成,5.已关闭)

        params.put("shippingStatus",1);
        params.put("enterpriseId",enterprise.getId());
        params.put("deleted",false);
        data.put("unconfirm",returnService.selectRowCount(params));

        params.clear();
        params.put("shippingStatus",3);
        params.put("enterpriseId",enterprise.getId());
        params.put("deleted",false);
        data.put("confirmed",returnService.selectRowCount(params));

        return CommResult.success(data);

    }


    /**
     * 查询单条退货单项
     *
     * @return
    */
    @ApiOperation("查询单条退货单项")
    @GetMapping("/find/{id}")
    public CommResult<Return> find(@PathVariable String id) {
        Return result = returnService.findById(id);

        Map<String,Object> data = new HashMap<>();
        data.put("return",result);


        if (result.getOrderId()!=null) {
            Order order = orderService.selectByPrimaryKey(result.getOrderId());
            data.put("receiverId",order.getReceiverId());

        }

        Map<String,Object> params = new HashMap<>();
        params.put("returnId",result.getId());
        result.setItemList(returnItemService.selectList(params));

        if (result.getOfficeId()!=null && !"".equals(result.getOfficeId())) {
            SysOffice sysOffice = sysOfficeService.selectByPrimaryKey(result.getOfficeId());
            if (sysOffice!=null) {
                data.put("officeName", sysOffice.getName());
            } else {
                data.put("officeName", "无");
            }
        } else {
            data.put("officeName", "无");
        }
        if (result.getShopId()!=null) {
            Shop shop = shopService.selectByPrimaryKey(result.getShopId());
            if (shop!=null) {
                data.put("shopName", shop.getName());
            }
        } else {
            data.put("shopName", "无");
        }
        if (result.getShippingEmployeeId()!=null) {
            SysEmployee shippingEmployee = sysEmployeeService.selectByPrimaryKey(result.getShippingEmployeeId());
            if (shippingEmployee!=null) {
                data.put("shippingEmployeeName", shippingEmployee.getName());
            }
        } else {
            data.put("shippingEmployeeName", "无");
        }

        if (result.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(result.getMemberId());
            if (member!=null) {
                data.put("memberName", member.getName());
            }
        } else {
            data.put("memberName", "无");
        }

        List<VirtualProduct> virtualProductList = new ArrayList<>();

        if (result.getOrderId()!=null) {
            Map<String, Object> paymentParams = new HashMap<>();
            paymentParams.put("orderType", 0);
            paymentParams.put("showed", 1);
            paymentParams.put("orderId", result.getOrderId());
            data.put("payments", paymentService.selectList(paymentParams));

            Map<String, Object> prms = new HashMap<>();
            prms.put("orderId", result.getOrderId());
            prms.put("sortField", "id");
            prms.put("sortType", "desc");
            data.put("orderLog", orderLogService.selectList(prms));


            Map<String, Object> virtualParams = new HashMap<>();
            virtualParams.put("orderId", result.getOrderId());
            virtualParams.put("sortField", "id");
            virtualParams.put("sortType", "desc");
            virtualProductList = virtualProductService.selectList(virtualParams);

        } else {
            Map<String, Object> paymentParams = new HashMap<>();
            paymentParams.put("orderType", 1);
            paymentParams.put("showed", 1);
            paymentParams.put("orderId", result.getWarehouseId());
            data.put("payments", paymentService.selectList(paymentParams));

        }

        Map<String, Object> virtualParams = new HashMap<>();
        virtualParams.put("shippingId", result.getId());
        virtualParams.put("sortField", "id");
        virtualParams.put("sortType", "desc");
        virtualProductList.addAll(virtualProductService.selectList(virtualParams));

        data.put("virtualProductList", virtualProductList);


        Map<String, Object> paymentParams = new HashMap<>();
        paymentParams.put("memberId", 0);
        paymentParams.put("status", 1);
        List<Receivable> receivableList = receivableService.selectList(paymentParams);
        Integer receivableQuantity = 0;
        BigDecimal receivableAmount = BigDecimal.ZERO;
        for (Receivable receivable:receivableList) {
            if ("paperPayPlugin".equals(receivable.getPaymentPluginId())) {
                receivableQuantity = receivableQuantity + receivable.getQuantityPaid();
            } else {
                receivableAmount = receivableAmount.add(receivable.getAmountPaid());
            }
        }

        data.put("receivableQuantity",receivableQuantity);
        data.put("receivableAmount", receivableAmount);

        return CommResult.success(data);

    }

    /**
     * 保存退货单项
     *
     * @param returns
     * @return
     */
    @ApiOperation("保存退货单项")
    @PostMapping("/save")
    public CommResult<Return> save(@RequestBody Return returns) {
        int affectCount = returnService.insert(returns);
        if (affectCount <= 0) {
            return CommResult.error();
        }
        Return result = returnService.findById(returns.getId());
        return CommResult.success(result);

    }

    /**
     * 批量删除退货单项
     *
     * @param ids
     * @return
     */
    @Log(desc = "批量删除退货单项", type = Log.LOG_TYPE.DEL)
    @ApiOperation("批量删除退货单项,ids用逗号拼接")
    @PostMapping("/del/{ids}")
    public CommResult<Return> del(@PathVariable String ids) {

        try {
            returnService.deleteByIds(ids.split(","));
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }
        return CommResult.success();
    }

    /**
     * 更新退货单项
     *
     * @param returns
     * @return
     */
    @Log(desc = "更新退货单项", type = Log.LOG_TYPE.UPDATE)
    @ApiOperation("更新退货单项")
    @PostMapping("/update")
    public CommResult<Return> update(@RequestBody Return returns) {
        int affectCount = returnService.updateByPrimaryKeySelective(returns);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Return result = returnService.findById(returns.getId());
        return CommResult.success(result);
    }

    /**
     * 退货确认
     *
     * @param id
     * @return
     */
    @ApiOperation("退货确认")
    @PostMapping("/received/{id}")
    public CommResult<Return> received(@PathVariable String id) {
        int affectCount = returnService.received(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Return result = returnService.findById(id);
        return CommResult.success(result);
    }

    /**
     * 退货完成
     *
     * @param id
     * @return
     */
    @ApiOperation("退货完成")
    @PostMapping("/complete/{id}")
    public CommResult<Return> complete(@PathVariable Long id) {
        int affectCount = returnService.complete(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Return result = returnService.findById(id);
        return CommResult.success(result);
    }


    /**
     * 退货关闭
     *
     * @param id
     * @return
     */
    @ApiOperation("退货关闭")
    @PostMapping("/cancel/{id}")
    public CommResult<Return> cancel(@PathVariable Long id) {
        int affectCount = returnService.cancel(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Return result = returnService.findById(id);
        return CommResult.success(result);
    }

    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("打印")
    @GetMapping("/print/{id}")
    public void print(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        Return order = returnService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("退货单不存在");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        if (null == enterprise) {
            throw new CustomException("没有开通企业");
        }
        SysOffice sysOffice = sysOfficeService.findById(order.getOfficeId());
        if (null != sysOffice){
            param.put("officeName",sysOffice.getOfficeName());
        }
        Shop shop = shopService.selectByPrimaryKey(order.getShopId());
        param.put("shopName", shop.getName());
        param.put("REPORT_NAME","退货单");
        param.put("COMPANY",enterprise.getName());
        param.put("enterpriseId",enterprise.getId());

        param.put("consignee", order.getConsignee());
        param.put("address", order.getAddress());
        param.put("phone", order.getPhone());
        param.put("orderDate", sdf.format(order.getOrderDate()));
        if (StringUtils.isNotEmpty(order.getMemo())){
            param.put("memo", order.getMemo());
        }else{
            param.put("memo", "");
        }

        param.put("sn", order.getSn());

        String memberName = "";
        Warehouse warehouse = warehouseService.selectByPrimaryKey(order.getWarehouseId());
        if (warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId()) ||
                warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())){
            Member member = memberService.selectByPrimaryKey(order.getMemberId());
            if (null != member){
                memberName = member.getName();
            }
        }else{
            Supplier supplier = supplierService.selectByPrimaryKey(order.getSupplierId());
            if (null != supplier){
                memberName = supplier.getName();
            }
        }
        param.put("memberName", memberName);

        String fileName = enterprise.getMchId()+"_"+order.getSn() + ".jasper";
        //fileName就是sys_report表的id
        SysReport sysReport = sysReportService.selectByPrimaryKey(fileName);

        String filePath = "";
        if (System.getProperty("os.name").contains("Windows")) {
            filePath = windowsFilePath;
        } else if (System.getProperty("os.name").contains("Linux")) {
            filePath = linuxFilePath;
        }
        //检查服务器上是否存在模板
        File file = new File(filePath + File.separator + fileName);
        if (!file.exists()){
            try {
                String url = sysReport == null?"":sysReport.getTemplate();
                sysReportService.fileDownLoad(response, url, filePath, fileName);
            } catch (Exception e){
                logger.info("打印模板下载失败");
                throw new CustomException("打印模板下载失败");
            }
        }

        String reportName = "returnPrint";
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT product_id, name, price, quantity, round(price*quantity, 2) amount, ");
        sql.append("    unit, spec, discount, sn, cost, shipping_freight, admin_freight, level_freight");
        sql.append(" FROM wx_return_item ");
        sql.append(" WHERE return_id  = "+id );
        File file2 = new File(filePath + File.separator + fileName);
        if (!file2.exists()) {
            //下载之后还不存在，就使用classpath路径的模板
            sysReportService.ReportToPdfBySql(reportName, param, sql.toString(), response);
        }else{
            sysReportService.commReportToPdf(filePath, fileName, param, sql.toString(), response);
        }

    }


    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("导出")
    @GetMapping("/export/{id}")
    public void export(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        Return order = returnService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("退货单不存在");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        if (null == enterprise) {
            throw new CustomException("没有开通企业");
        }
        SysOffice sysOffice = sysOfficeService.findById(order.getOfficeId());
        if (null != sysOffice){
            param.put("officeName",sysOffice.getOfficeName());
        }
        Shop shop = shopService.selectByPrimaryKey(order.getShopId());
        param.put("shopName", shop.getName());
        param.put("REPORT_NAME","退货单");
        param.put("COMPANY",enterprise.getName());
        param.put("enterpriseId",enterprise.getId());

        param.put("consignee", order.getConsignee());
        param.put("address", order.getAddress());
        param.put("phone", order.getPhone());
        param.put("orderDate", sdf.format(order.getOrderDate()));
        if (StringUtils.isNotEmpty(order.getMemo())){
            param.put("memo", order.getMemo());
        }else{
            param.put("memo", "");
        }

        param.put("sn", order.getSn());

        String memberName = "";
        Warehouse warehouse = warehouseService.selectByPrimaryKey(order.getWarehouseId());
        if (warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId()) ||
                warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())){
            Member member = memberService.selectByPrimaryKey(order.getMemberId());
            if (null != member){
                memberName = member.getName();
            }
        }else{
            Supplier supplier = supplierService.selectByPrimaryKey(order.getSupplierId());
            if (null != supplier){
                memberName = supplier.getName();
            }
        }
        param.put("memberName", memberName);

        String reportName = "returnPrint";
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT product_id, name, price, quantity, round(price*quantity, 2) amount, ");
        sql.append("    unit, spec, discount, sn, cost, shipping_freight, admin_freight, level_freight");
        sql.append(" FROM wx_return_item ");
        sql.append(" WHERE return_id  = "+id );
        sysReportService.ReportToExcelBySql(reportName, param, sql.toString(),response);
    }

}
